package acn.spring.shop.controllers;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.ModelAndView;

import acn.spring.domain.Order;
import acn.spring.domain.Product;
import acn.spring.service.ShopService;
import acn.spring.shop.viewUtil.PageWrapper;
import acn.spring.shop.viewUtil.RequestMappings;
import acn.spring.shop.viewUtil.ViewNames;

@Controller
@RequestMapping(RequestMappings.PRODUCTS)
@SessionAttributes("order")
public class ProductController {

	private ShopService shopService;

	@Autowired
	public ProductController(ShopService shopService) {
		this.shopService = shopService;
	}

	@ModelAttribute
	public Order createOrder() {
		return new Order();
	}

	@RequestMapping("/home")
	public String home() {
		return "home";
	}

	@RequestMapping
	public String showAllProducts(Model model, Pageable pageable, HttpServletRequest request) {

		Page<Product> page = shopService.getAllProducts(pageable);
		PageWrapper<Product> pageWrapper = new PageWrapper<Product>(page, request.getRequestURI(),
				pageable.getPageSize());
		model.addAttribute("page", pageWrapper);

		return ViewNames.ALL_PRODUCTS;
	}

	@RequestMapping(value = RequestMappings.SHOW_PRODUCT, method = RequestMethod.GET)
	public String showProduct(@PathVariable(RequestMappings.PARAM_PRODUCT_ID) Product product) {
		return ViewNames.PRODUCT;
	}

	@RequestMapping(value = RequestMappings.ADD_TO_CART, method = RequestMethod.GET)
	public String addToCart(@RequestParam Product product, @ModelAttribute Order order) {
		order.addProduct(product);
		return ViewNames.SHOPPING_CART;
	}

	@RequestMapping(value = RequestMappings.DELETE_FROM_CART, method = RequestMethod.GET)
	public String deleteFromCart(@RequestParam Product product, @ModelAttribute Order order) {
		order.removeProduct(product);
		return ViewNames.SHOPPING_CART;
	}

	@RequestMapping(value = RequestMappings.CLEAR_CART, method = RequestMethod.GET)
	public String clearCart(@ModelAttribute Order order, SessionStatus status) {

		order.removeAllProducts();
		status.setComplete();

		return RequestMappings.REDIRECT_PRODUCTS;
	}

	@RequestMapping(value = RequestMappings.ADD_NEW_PRODUCT, method = RequestMethod.GET)
	public String showProductForm(@ModelAttribute Product product) {
		return ViewNames.PRODUCT_FORM;
	}

	@RequestMapping(value = { RequestMappings.ADD_NEW_PRODUCT, "/edit/{productId}" }, method = RequestMethod.POST)
	public String processProductForm(@Valid Product product, BindingResult result) {

		if (result.hasErrors()) {
			return ViewNames.PRODUCT_FORM;
		}

		shopService.addProduct(product);

		return RequestMappings.REDIRECT_PRODUCTS;
	}

	@RequestMapping(value = RequestMappings.EDIT + RequestMappings.PARAM_PRODUCT_ID, method = RequestMethod.GET)
	public @ResponseBody String showEditForm(@PathVariable Integer productId) {

		ModelAndView returned = new ModelAndView();
		returned.setViewName("productForm");

		Product product = shopService.getProduct(productId);

		return product.getId().toString();

		// returned.addObject("itemObject", item);
		// return returned;
	}

	@RequestMapping(value = "/showAllProductsJSON")
	public @ResponseBody List<Product> showAllProductsJSON() {
		return shopService.getAllProducts();
	}

}
